package compilador.semantico;

public class GerenciadorDeContexto {
	private Variavel[] variavel = new Variavel[256];
	private Tipo contextoDefault;
	private int i = -1;
	private int metodoIndex = 0;

	private GerenciadorDeContexto() {
	}

	private static GerenciadorDeContexto instance = new GerenciadorDeContexto();

	public static GerenciadorDeContexto getInstance() {
		return instance;
	}

	/**
	 * Zera a pilha
	 */
	public void reset() {
		variavel = new Variavel[256];
		i = -1;
	}

	public int getMetodoIndex() {
		return metodoIndex;
	}

	public void zeraMetodoIndex() {
		metodoIndex = 0;
	}

	public void incMetodoIndex() {
		metodoIndex++;
	}

	/**
	 * aloca um novo endereço
	 */
	public void cria() {
		if ( i < 0 || variavel[i] != null)
			i++;
	}

	/**
	 * Recupera o ultimo contexto adicionado ou o contextoDefault
	 */
	public Variavel top() {
		if (i == -1 || variavel[i] == null)
			return this.contextoDefault;
		return this.variavel[i];
	}

	/**
	 * remove o valor do topo da pilha e decrementa
	 */
	public void remove() {
		variavel[i] = null;
		i--;
	}

	/**
	 * Adiciona uma variavel a posicao corrente
	 */
	public void push(Variavel variavel) {
		this.variavel[i] = variavel;
	}

	/**
	 * Seta o contexto default da pilha
	 */
	public void setDefaultContext(Tipo context) {
		this.contextoDefault = context;
	}

	/**
	 * Recupera o contexto default da pilha
	 */
	public Tipo getDefaultContext() {
		return this.contextoDefault;
	}

	/**
	 * verifica se a posicao corrente esta vazia
	 */
	public boolean isEmpty() {
		return variavel[i] == null;
	}

	@Override
	public String toString() {
		StringBuilder buf = new StringBuilder();
		for (int j = 0; j <= i; j++) {
			Variavel v = variavel[j];
			buf.append("->");
			if (v != null) {
				buf.append(v.getNome());
				buf.append(':');
				buf.append(v.getTipo());
			} 
		}
		return buf.toString();
	}
}
